package com.hd.trans.files.model;

import android.app.Application;
import android.media.MediaMetadataRetriever;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import com.hd.trans.files.bean.Audio;
import com.hd.trans.files.bean.Video;
import com.hd.trans.files.domain.RequestVideoDataUserCase;
import com.hd.trans.files.domain.SearchVideoUseCase;
import com.hd.trans.files.interf.OnShowScanFileInterface;
import com.hd.trans.files.sort.MediaSortHelper;
import com.hd.trans.utils.FileUtils;
import com.hd.trans.utils.SharedFileUtils;
import com.hd.trans.utils.StorageUtils;

import java.io.File;
import java.io.FileFilter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.core.SingleOnSubscribe;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;

/**
 * 本地文件路径查找文件
 */
public class FilesPathViewModel extends BaseViewModel {

    private String mCurrentPath;
    private String mLastKeyWord = "";
    private Disposable mLoadFilesDisposable;
    private Disposable mSearchDisposable;

    private MusicItems mAudioFileProvider;
    private final File mSdRootPath = new File(FileUtils.getStorageDirectory());
    private final String mRootPath = mSdRootPath.getPath();

    private List<Audio> mAudioData = new ArrayList<>();

    private final MutableLiveData<String> mCurrentPathObserver = new MutableLiveData<>();
    private final MutableLiveData<Boolean> mLoadingObserver = new MutableLiveData<>();

    // 当前扫描路径
    private final MutableLiveData<String> mScanPathObserver = new MutableLiveData<>();
    // 音频
    private final MutableLiveData<List<Audio>> mAudiosDataObserver = new MutableLiveData<>();
    private final MutableLiveData<List<Audio>> mSearchAudioObserver = new MutableLiveData<>();
    // 视频
    private final MutableLiveData<List<Video>> mVideoDataObserver = new MutableLiveData<>();
    private final MutableLiveData<List<Video>> mSearchVideoObserver = new MutableLiveData<>();

    // 视频数据获取
    private RequestVideoDataUserCase mVideoDataUserCase;
    // 视频搜索业务逻辑
    private SearchVideoUseCase mSearchVideoUseCase;

    public FilesPathViewModel(@NonNull Application application) {
        super(application);
        setProgressUiViewModel(new ProgressUiViewModel());
    }

    @Override
    public void onCreate(@NonNull LifecycleOwner owner) {
        loadLocalAudios(mSdRootPath.getAbsolutePath());
    }

    @Override
    protected void onCleared() {
        if (mLoadFilesDisposable != null) {
            mLoadFilesDisposable.dispose();
        }
        if (mSearchDisposable != null) {
            mSearchDisposable.dispose();
        }
        if (mAudioFileProvider != null) {
            mAudioFileProvider.clear();
        }
        super.onCleared();
    }

    /**
     * 手机返回事件
     */
    public void onBackPressed(String path) {
        loadLocalAudios(path);
    }

    public String getLastKeyWord() {
        return mLastKeyWord;
    }

    public MutableLiveData<List<Video>> getSearchVideoObserver() {
        return mSearchVideoObserver;
    }

    public MutableLiveData<Boolean> getLoadingObserver() {
        return mLoadingObserver;
    }

    public MutableLiveData<String> getScanPathObserver() {
        return mScanPathObserver;
    }

    public MutableLiveData<List<Audio>> getAudiosDataObserver() {
        return mAudiosDataObserver;
    }

    public MutableLiveData<String> getCurrentPathObserver() {
        return mCurrentPathObserver;
    }

    public MutableLiveData<List<Audio>> getSearchAudioObserver() {
        return mSearchAudioObserver;
    }

    public MutableLiveData<List<Video>> getVideoDataObserver() {
        return mVideoDataObserver;
    }

    /**
     * 加载路径下的文件夹和视频
     */
    /*public void loadLocalVideos(String path) {
        mCurrentPath = path;
        FileSortModel.ModeItem sortModeItem = SharedFileUtils.getInstance(getApplication())
                .getFileSortModeItem();
        mVideoDataUserCase.addVideoDataObserver(mVideoDataObserver)
                .addCurrentPathObserver(mCurrentPathObserver)
    }*/

    /**
     * 加载路径下的文件夹和音频
     */
    public void loadLocalAudios(final String path) {
        mLoadFilesDisposable = Single.create((SingleOnSubscribe<List<Audio>>)
                emitter -> emitter.onSuccess(taskLoadLocalDir(path)))
                .map(audio -> MediaSortHelper.getInstance().sortAudio(audio, getSortModeItem()))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe((audio, throwable) -> {
                    mAudioData = audio;
                    mAudiosDataObserver.setValue(audio);
                });
    }

    private File getCurrentFile(String url) {
        if (!url.equals(mRootPath)) {
            // 获取这个路径下的所有文件及目录
            return new File(url);
        } else {
            // 获取根目录File对象
            return new File(mRootPath);
        }
    }

    // 获取这个路径下的所有文件及目录
    private List<Audio> taskLoadLocalDir(String directory) {
        List<Audio> mAudioList = new ArrayList<>();
        File[] files; // File数组
        File currentFile = getCurrentFile(directory);
        files = currentFile.listFiles(mFileFilter);
        mCurrentPath = currentFile.getPath();
        mCurrentPathObserver.postValue(mCurrentPath);
        if (files == null) {
            files = new File[0];
        }
        File tStorageRootDir = new File(StorageUtils.getStorageDirectory());
        // 遍历这个路径下所有的文件夹和文件
        for (File value : files) {
            long lastModified = value.lastModified();
            Audio audio = new Audio(0, value.getName(), value.getAbsolutePath(), lastModified, 0, value.length());
            if (value.isDirectory()) {
                // 判断该文件是否是文件夹并且屏蔽程序自身的文件夹
                if (isFilterDirectoryOrFile(value.getName())) {
                    continue;
                }
                if (!value.getParent().equals(tStorageRootDir.getParent()) || value.getPath().equals(tStorageRootDir.getPath())) {
//                    audio.setImageRes(R.drawable.icon_list_folder_blue);
                    audio.setDisplay_name(value.getName());
                    audio.setUrl(value.getAbsolutePath());
                    String time = new SimpleDateFormat("yyyy-MM-dd").format(new Date(lastModified));
                    audio.setYear(time);
                    audio.setTimes(lastModified);
                    audio.setSize((value.length()));
                    audio.setDir(true);
                    mAudioList.add(audio);
                }
            } else if (value.isFile() && isMusicAvailable(value.getAbsolutePath())) {
                String time = new SimpleDateFormat("yyyy-MM-dd").format(new Date(lastModified));
                audio.setYear(time);
                audio.setSize(value.length());
//                audio.setImageRes(R.drawable.icon_sdk_playing);
                audio.setDisplay_name(value.getName());
                audio.setUrl(value.getAbsolutePath());
                audio.setTimes(lastModified);
                MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//                long duration = AudioUtils.getMusicItemDuration(audio.getUrl(), retriever);
                retriever.setDataSource(audio.getUrl());
//                audio.setDurations(duration);
//                audio.setDuration(duration);
                mAudioList.add(audio);
            }
        }
        return mAudioList;
    }

    /**
     * 过滤文件
     */
    private final FileFilter mFileFilter = pathname -> !pathname.isHidden();

    private boolean isMusicAvailable(String path) {
        if (!TextUtils.isEmpty(path)) {
            File file = new File(path);
            return MusicItem.checkValidExtMusicFile(path) && file.exists();
        } else {
            return false;
        }
    }

    /**
     * 过滤文件
     *
     * @param name
     * @return
     */
    private boolean isFilterDirectoryOrFile(String name) {
        return name.equals("17rd") || name.equals("proc");
    }

    public void doSearch(String keyWord) {
        if (!keyWord.isEmpty() && TextUtils.equals(keyWord, mLastKeyWord)) {
            return;
        }
            if (mAudioFileProvider != null) {
                mAudioFileProvider.setIsCancel(true);
            }
            if (mSearchDisposable != null && !mSearchDisposable.isDisposed()) {
                mSearchDisposable.dispose();
            }
            if (TextUtils.isEmpty(keyWord)) {
                loadLocalAudios(mCurrentPath);
                mLoadingObserver.setValue(false);
            } else {
                final ArrayList<String> allPaths = new ArrayList<>();
                for (Audio audio : mAudioData) {
                    allPaths.add(audio.getUrl());
                }
                mAudioFileProvider = createMusicItems();
                mSearchDisposable = taskSearch(allPaths, keyWord);
        }
        mLastKeyWord = keyWord;
    }


    private FileSortModel.ModeItem getSortModeItem() {
        return SharedFileUtils.getInstance(getApplication()).getFileSortModeItem();
    }

    private Disposable taskSearch(ArrayList<String> allPaths, String keyWord) {
        return Single.create((SingleOnSubscribe<List<Audio>>) emitter -> {
            mLoadingObserver.postValue(true);
            emitter.onSuccess(mAudioFileProvider.loadMusicItems(3, allPaths, keyWord));
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(searchAudio -> {
                    mSearchAudioObserver.setValue(searchAudio);
                    mLoadingObserver.setValue(false);
                });
    }

    private MusicItems createMusicItems() {
        MusicItems musicProvider = new MusicItems(getApplication());
        musicProvider.setOnShowScanFileInterface(new OnShowScanFileInterface() {
            @Override
            public void scanFilePath(String path) {
                // 显示文件当前路径
                mScanPathObserver.postValue(path);
            }

            @Override
            public void scanNewFileNum(int newNum) {

            }
        });
        return musicProvider;
    }

    public static class FilesPathViewModelFactory implements ViewModelProvider.Factory {

        private final Application mApplication;

        public FilesPathViewModelFactory(Application application) {
            this.mApplication = application;
        }

        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            return (T) new FilesPathViewModel(mApplication);
        }
    }
}
